#include <string.h>
#include "Transport.h"
#include "esp_log.h"
#include "driver/i2s.h"
#include "raw_stream.h"
#include "board.h"

static const char *TAG = "dez_espnow";
static xQueueHandle s_dez_espnow_queue;

extern audio_element_handle_t raw_stream_writer;

// static uint16_t s_dez_espnow_seq[DEZ_ESPNOW_DATA_MAX] = {0, 0};
static uint8_t s_dez_broadcast_mac[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static void dez_espnow_send_cb(const uint8_t *mac_addr, esp_now_send_status_t status);
static void dez_espnow_recv_cb(const uint8_t *mac_addr, const uint8_t *data, int len);

/**
 * @brief  initialize wifi
 */
void dez_wifi_init(void)
{
    // ESP_LOGI(TAG, "WIFI 初始化");
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    ESP_ERROR_CHECK(esp_wifi_set_mode(ESPNOW_WIFI_MODE));
    // vTaskDelay(3000 / portTICK_RATE_MS);
    int e = (int)esp_wifi_start();

#if CONFIG_ESPNOW_ENABLE_LONG_RANGE
    ESP_ERROR_CHECK(esp_wifi_set_protocol(ESPNOW_WIFI_IF, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR));
#endif
    ESP_LOGI(TAG, "WIFI 初始化完成");
}

// void dez_espnow_deinit(dez_espnow_send_param_t *send_param)
// {
//     free(send_param->buffer);
//     free(send_param);
//     vSemaphoreDelete(s_dez_espnow_queue);
//     esp_now_deinit();
// }

/**
 * @brief  ESPNOW send voice
 */
void sendVoice(const uint8_t *data, uint16_t len)
{
    // printf("send voice address  %p",data);
    // ESP_LOGI(TAG, "Sending voice");
    while (0 == sendDone)
    {
        // ESP_LOGI(TAG, "等待发送................");
        vTaskDelay(10 / portTICK_RATE_MS); // 100 perfect
    }
    sendDone = 0;
    // ESP_LOGI(TAG, "Sending voice bytes%d", len);
    // ESP_LOGI(TAG, "send CRC%d", esp_crc16_le(UINT16_MAX, (uint8_t const *)data, (uint32_t)len));
    esp_now_send(s_dez_broadcast_mac, data, len);
}

/**
 * @brief  send callback
 */
static void dez_espnow_send_cb(const uint8_t *mac_addr, esp_now_send_status_t status)
{
    // ESP_LOGI(TAG, "Sending voice Done!!!!!!!!!!");
    sendDone = 1;
}

/**
 * @brief  recive callback
 */
static void dez_espnow_recv_cb(const uint8_t *mac_addr, const uint8_t *data, int len)
{
    // recOver=0;// initiate
    // gpio_set_level(get_pa_enable_gpio(), 1);
    // ESP_LOGI(TAG, "CRC%d", esp_crc16_le(UINT16_MAX, (uint8_t const *)data, (uint32_t)len));

    if (1 == speaking) // 限制发送语音时不接收语音
    {
        return;
    }

    if (AUDIT_BIT == 16)
    {
        //=============16bit=============
        int k = 0;
        int j = len / sizeof(uint16_t);
        for (int i = 0; i < j; i++)
        {
            k = i * 2;
            output_16bit[i] = (uint16_t)(data[k] << 0) | (uint16_t)(data[k + 1] << 8);
        }
        // printf("output data 16 bit len %d\n",len);
        int writeLen = raw_stream_write(raw_stream_writer, (char *)output_16bit, len);
    }
    else if (AUDIT_BIT == 32)
    {
        //=============32bit=============
        int k = 0;
        int j = len / sizeof(uint32_t);
        for (int i = 0; i < j; i++)
        {
            k = i * 4;
            output_32bit[i] = (uint32_t)(data[k] << 0) | (uint32_t)(data[k + 1] << 8) | (uint32_t)(data[k + 2] << 16) | (uint32_t)(data[k + 3] << 24);
        }
        // printf("output data %x,%x,%x,%x\n", data[0], data[1], data[2], data[3]);
        // printf("output data len %d\n",len);

        int writeLen = raw_stream_write(raw_stream_writer, (char *)output_32bit, len);
    }
    //  =============8bit=============
    // int writeLen=raw_stream_write(raw_stream_writer, (char *)data, len);

    recOver = 1;
    // gpio_set_level(get_pa_enable_gpio(), 0);
}

esp_err_t dez_espnow_init(void)
{
    ESP_LOGI(TAG, "Initialize ESP NOW");
    // dez_espnow_send_param_t *send_param;

    s_dez_espnow_queue = xQueueCreate(ESPNOW_QUEUE_SIZE, sizeof(dez_espnow_event_t));
    if (s_dez_espnow_queue == NULL)
    {
        ESP_LOGE(TAG, "Create mutex fail");
        return ESP_FAIL;
    }
    // ESP_ERROR_CHECK(esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_MCS7_SGI))
    /* Initialize ESPNOW and register sending and receiving callback function. */
    ESP_ERROR_CHECK(esp_now_init());
    ESP_ERROR_CHECK(esp_now_register_send_cb(dez_espnow_send_cb));
    ESP_ERROR_CHECK(esp_now_register_recv_cb(dez_espnow_recv_cb));

    /* Set primary master key. */
    ESP_ERROR_CHECK(esp_now_set_pmk((uint8_t *)CONFIG_ESPNOW_PMK));
    esp_now_peer_info_t *peer = malloc(sizeof(esp_now_peer_info_t));
    if (peer == NULL)
    {
        ESP_LOGE(TAG, "Malloc peer information fail");
        vSemaphoreDelete(s_dez_espnow_queue);
        esp_now_deinit();
        return ESP_FAIL;
    }
    memset(peer, 0, sizeof(esp_now_peer_info_t));
    peer->channel = CONFIG_ESPNOW_CHANNEL;
    peer->ifidx = ESPNOW_WIFI_IF;
    peer->encrypt = false;
    memcpy(peer->peer_addr, s_dez_broadcast_mac, ESP_NOW_ETH_ALEN);
    ESP_ERROR_CHECK(esp_now_add_peer(peer));
    free(peer);
    ESP_LOGI(TAG, "ESP NOW 初始化完成");
    return ESP_OK;
}
